
#include <memory>

extern "C" {
#include <zepplist.h>
}

#include <gtest/gtest.h>

TEST(ListTest, InsertList) {
  int test_list_length = 5;
  int datacount = 10 * Datasize;

  std::unique_ptr<struct list_head, decltype(&destroy_list)> list(
      create_list_head(), &destroy_list);
  init_list_head(list.get());

  int t = 0;
  for (int i = 0; i < test_list_length; i++) {
    struct list_node *node = create_list_node();
    auto tail = list->tail;
    insert_list_tail(list.get(), node);
    EXPECT_EQ(tail, list->tail->prev)
        << "old tail: " << tail << "new tail.prev: " << list->tail->prev;
    EXPECT_EQ(tail->next, list->tail)
        << "old tail.next: " << tail->next << "new tail: " << list->tail;
    for (int j = 0; j < Datasize; j++) {
      node->datas[j] = t++;
    }
  }

  EXPECT_EQ(test_list_length, list->size)
      << "test_list_length: " << test_list_length << "list.size" << list->size;
}

TEST(ListTest, RemoveList) {
  int test_list_length = 5;

  std::unique_ptr<struct list_head, decltype(&destroy_list)> list(
      create_list_head(), &destroy_list);
  init_list_head(list.get());

  // 插入测试节点
  for (int i = 0; i < test_list_length; i++) {
    struct list_node *node = create_list_node();
    insert_list_tail(list.get(), node);
  }

  // 删除一个节点
  struct list_node *node_to_remove = list->head;
  struct list_node *next_node = node_to_remove->next;
  list_remove(list.get(), node_to_remove);

  // 验证删除后的链表状态
  EXPECT_EQ(test_list_length - 1, list->size);
  EXPECT_EQ(next_node, list->head);
}

TEST(ListTest, TraverseList) {
  int test_list_length = 5;
  int datacount = 10 * Datasize;

  std::unique_ptr<struct list_head, decltype(&destroy_list)> list(
      create_list_head(), &destroy_list);
  init_list_head(list.get());

  int t = 0;
  for (int i = 0; i < test_list_length; i++) {
    struct list_node *node = create_list_node();
    insert_list_tail(list.get(), node);
    for (int j = 0; j < Datasize; j++) {
      node->datas[j] = t++;
    }
  }

  // 遍历链表验证数据
  int count = 0;
  struct list_node *pos;
  list_foreach(list->head, list->nil, pos) {
    for (int j = 0; j < Datasize; j++) {
      EXPECT_EQ(count, pos->datas[j]);
      count++;
    }
  }
  EXPECT_EQ(test_list_length * Datasize, count);
}

TEST(ListTest, SwapNode) {
  std::unique_ptr<struct list_head, decltype(&destroy_list)> list(
      create_list_head(), &destroy_list);
  init_list_head(list.get());

  // 创建三个节点
  struct list_node *node1 = create_list_node();
  struct list_node *node2 = create_list_node();
  struct list_node *node3 = create_list_node();

  // 初始化节点数据
  for (int i = 0; i < Datasize; i++) {
    node1->datas[i] = 1;
    node2->datas[i] = 2;
    node3->datas[i] = 3;
  }

  // 插入节点到链表
  insert_list_tail(list.get(), node1);
  insert_list_tail(list.get(), node2);
  insert_list_tail(list.get(), node3);

  EXPECT_EQ(list->head, node1);
  EXPECT_EQ(list->tail, node3);

  // 交换节点1和节点3
  list_swap_node(list.get(), node1, node3);

  // 验证交换结果
  EXPECT_EQ(list->head, node3);
  EXPECT_EQ(list->head->next, node2);
  EXPECT_EQ(list->head->next->next, node1);
  EXPECT_EQ(list->tail, node1);
}


TEST(ListTest, GetData) {
  int test_list_length = 5;
  int datacount = test_list_length * Datasize;

  std::unique_ptr<struct list_head, decltype(&destroy_list)> list(
      create_list_head(), &destroy_list);
  init_list_head(list.get());

  int t = 0;
  for (int i = 0; i < test_list_length; i++) {
    struct list_node *node = create_list_node();
    insert_list_tail(list.get(), node);
    for (int j = 0; j < Datasize; j++) {
      node->datas[j] = t++;
    }
  }

  for (int i = 0; i < test_list_length; i++) {
    auto node = get_index_block(list.get(), i);
    for (int j = 0; j < Datasize; j++) {
      EXPECT_EQ(i * Datasize + j, node->datas[j]);
    }
  }
}
